package com.opencee.cloud.api.gateway.locator;

import com.opencee.cloud.api.gateway.util.matcher.ReactiveRequestMatcher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.security.access.ConfigAttribute;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 资源加载器
 *
 * @author liuyadu
 */
@Slf4j
public class ApiControlLocator  {


    /**
     * 秒
     */
    public static final long SECONDS = 1;
    /**
     * 1分钟
     */
    public static final long SECONDS_IN_MINUTE = 60;
    /**
     * 一小时
     */
    public static final long SECONDS_IN_HOUR = 3600;
    /**
     * 一天
     */
    public static final long SECONDS_IN_DAY = 24 * 3600;

    /**
     * 请求总时长
     */
    public static final int PERIOD_SECOND_TTL = 10;
    public static final int PERIOD_MINUTE_TTL = 2 * 60 + 10;
    public static final int PERIOD_HOUR_TTL = 2 * 3600 + 10;
    public static final int PERIOD_DAY_TTL = 2 * 3600 * 24 + 10;


 /*   *//**
     * 权限集合
     *//*
    private Map<ReactiveRequestMatcher, ResourceInfo> grantedAuthorities;

    *//**
     * ip黑名单
     *//*
    private Map<ReactiveRequestMatcher, IpLimitApiVo> ipBlacks;

    *//**
     * ip白名单
     *//*
    private Map<ReactiveRequestMatcher, IpLimitApiVo> ipWhites;*/

    /**
     * 权限列表
     */
    private Map<ReactiveRequestMatcher, Collection<ConfigAttribute>> configAttributes;


    private RouteDefinitionLocator routeDefinitionLocator;

    public ApiControlLocator() {
     /*   this.grantedAuthorities = new ConcurrentHashMap<>();
        this.ipBlacks = new ConcurrentHashMap<>();
        this.ipWhites = new ConcurrentHashMap<>();*/
        this.configAttributes = new ConcurrentHashMap<>();
    }


    public ApiControlLocator(RouteDefinitionLocator routeDefinitionLocator) {
        this();
        //this.systemAuthorityServiceClient = systemAuthorityServiceClient;
        //this.gatewayServiceClient = gatewayServiceClient;
        this.routeDefinitionLocator = routeDefinitionLocator;
    }


    /**
     * 清空缓存并刷新
     */
   /* public void refresh() {
        loadApis();
        loadIpBlackList();
        loadIpWhiteList();
    }



    *//**
     * 查询路由后的地址
     *
     * @return
     *//*
    protected String getFullPath(String serviceId, String path) {
        final String[] fullPath = {path.startsWith("/") ? path : "/" + path};
        routeDefinitionLocator.getRouteDefinitions()
                .filter(routeDefinition -> routeDefinition.getId().equals(serviceId))
                .subscribe(routeDefinition -> {
                            routeDefinition.getPredicates().stream()
                                    .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                                    .filter(predicateDefinition -> !predicateDefinition.getArgs().containsKey("_rateLimit"))
                                    .forEach(predicateDefinition -> {
                                        fullPath[0] = predicateDefinition.getArgs().get("pattern").replace("/**", path.startsWith("/") ? path : "/" + path);
                                    });
                        }
                );
        return fullPath[0];
    }

    *//**
     * 加载授权列表
     *//*
    public void loadApis() {
        Map<ReactiveRequestMatcher, Collection<ConfigAttribute>> configAttributeMap = new LinkedHashMap<>();
        Map<ReactiveRequestMatcher, ResourceInfo> grantedAuthorityInfoMap = new LinkedHashMap<>();
        Collection<ConfigAttribute> list;
        ConfigAttribute cfg;
        try {
            // 查询所有API
            List<ResourceInfo> apiList = systemAuthorityServiceClient.findAll().getData();
            if (apiList != null && !apiList.isEmpty()) {
                for (ResourceInfo item : apiList) {
                    String path = item.getPath();
                    if (path == null) {
                        continue;
                    }
                    String fullPath = getFullPath(item.getServiceId(), path);
                    item.setPath(fullPath);
                    ReactiveRequestMatcher requestMatcher = new ReactiveAntPathRequestMatcher(fullPath, item.getHttpMethod());
                    list = configAttributeMap.get(requestMatcher);
                    if (list == null) {
                        list = new ArrayList<>();
                    }
                    if (!list.contains(item.getAuthority())) {
                        cfg = new SecurityConfig(item.getAuthority());
                        list.add(cfg);
                    }
                    configAttributeMap.put(requestMatcher, list);
                    grantedAuthorityInfoMap.put(requestMatcher, item);
                }
                this.configAttributes.clear();
                this.grantedAuthorities.clear();
                this.configAttributes.putAll(configAttributeMap);
                this.grantedAuthorities.putAll(grantedAuthorityInfoMap);
                log.info("=============加载动态权限:{}==============", grantedAuthorities.size());
            }
        } catch (Exception e) {
            log.error("加载动态权限错误:{}", e);
        }
    }

    *//**
     * 加载IP黑名单
     *//*
    public void loadIpBlackList() {
        Map<ReactiveRequestMatcher, IpLimitApiVo> apiMap = new LinkedHashMap<>();
        *//*try {
            List<IpLimitApi> list = gatewayServiceClient.getBlackApiList().getData();
            if (list != null && !list.isEmpty()) {
                for (IpLimitApi item : list) {
                    String fullPath = getFullPath(item.getServiceId(), item.getPath());
                    item.setPath(fullPath);
                    ReactiveRequestMatcher requestMatcher = new ReactiveAntPathRequestMatcher(fullPath, item.getHttpMethod());
                    apiMap.put(requestMatcher, item);
                }
                this.ipBlacks.clear();
                this.ipBlacks.putAll(apiMap);
                log.info("=============加载IP黑名单:{}==============", list.size());
            }
        } catch (Exception e) {
            log.error("加载IP黑名单错误:{}", e);
        }*//*
    }

    *//**
     * 加载IP白名单
     *//*
    public void loadIpWhiteList() {
        Map<ReactiveRequestMatcher, IpLimitApiVo> apiMap = new LinkedHashMap<>();
      *//*  try {
            List<IpLimitApi> list = gatewayServiceClient.getWhiteApiList().getData();
            if (list != null && !list.isEmpty()) {
                for (IpLimitApi item : list) {
                    String fullPath = getFullPath(item.getServiceId(), item.getPath());
                    item.setPath(fullPath);
                    ReactiveRequestMatcher requestMatcher = new ReactiveAntPathRequestMatcher(fullPath, item.getHttpMethod());
                    apiMap.put(requestMatcher, item);
                }
                this.ipWhites.clear();
                this.ipWhites.putAll(apiMap);
                log.info("=============加载IP白名单:{}==============", list.size());
            }
        } catch (Exception e) {
            log.error("加载IP白名单错误:{}", e);
        }*//*
    }

    *//**
     * 查询单位时间内刷新时长和请求总时长
     *
     * @param timeUnit
     * @return
     *//*
    public static long[] getIntervalAndQuota(String timeUnit) {
        if (timeUnit.equalsIgnoreCase(TimeUnit.SECONDS.name())) {
            return new long[]{SECONDS, PERIOD_SECOND_TTL};
        } else if (timeUnit.equalsIgnoreCase(TimeUnit.MINUTES.name())) {
            return new long[]{SECONDS_IN_MINUTE, PERIOD_MINUTE_TTL};
        } else if (timeUnit.equalsIgnoreCase(TimeUnit.HOURS.name())) {
            return new long[]{SECONDS_IN_HOUR, PERIOD_HOUR_TTL};
        } else if (timeUnit.equalsIgnoreCase(TimeUnit.DAYS.name())) {
            return new long[]{SECONDS_IN_DAY, PERIOD_DAY_TTL};
        } else {
            throw new IllegalArgumentException("Don't support this TimeUnit: " + timeUnit);
        }
    }

    public Map<ReactiveRequestMatcher, ResourceInfo> getGrantedAuthorities() {
        return grantedAuthorities;
    }

    public void setGrantedAuthorities(Map<ReactiveRequestMatcher, ResourceInfo> grantedAuthorities) {
        this.grantedAuthorities = grantedAuthorities;
    }

    public Map<ReactiveRequestMatcher, IpLimitApiVo> getIpBlacks() {
        return ipBlacks;
    }

    public void setIpBlacks(Map<ReactiveRequestMatcher, IpLimitApiVo> ipBlacks) {
        this.ipBlacks = ipBlacks;
    }

    public Map<ReactiveRequestMatcher, IpLimitApiVo> getIpWhites() {
        return ipWhites;
    }

    public void setIpWhites(Map<ReactiveRequestMatcher, IpLimitApiVo> ipWhites) {
        this.ipWhites = ipWhites;
    }

    public Map<ReactiveRequestMatcher, Collection<ConfigAttribute>> getConfigAttributes() {
        return configAttributes;
    }

    public void setConfigAttributes(Map<ReactiveRequestMatcher, Collection<ConfigAttribute>> configAttributes) {
        this.configAttributes = configAttributes;
    }


    public GatewayClient getGatewayServiceClient() {
        return gatewayServiceClient;
    }

    public void setGatewayServiceClient(GatewayClient gatewayServiceClient) {
        this.gatewayServiceClient = gatewayServiceClient;
    }

    public RouteDefinitionLocator getRouteDefinitionLocator() {
        return routeDefinitionLocator;
    }

    public void setRouteDefinitionLocator(RouteDefinitionLocator routeDefinitionLocator) {
        this.routeDefinitionLocator = routeDefinitionLocator;
    }*/
}
